package servidor.controle;

import java.sql.SQLException;
import java.util.ArrayList;

import servidor.modelo.Cliente;
import servidor.modelo.Conta;
import servidor.modelo.Gerente;
import servidor.modelo.TipoPessoa;

public class ClienteControlador {

	public static void cria(Gerente gerente, String nome, String login,
			String email, String senha, TipoPessoa tipoDePessoa, String cpfCnpj)
			throws SQLException {
		Sistema sistema = Sistema.getUnicaInstancia();
		Cliente cliente = sistema.getEntityManager().create(Cliente.class);
		UsuarioControlador.atualiza(cliente, nome, login, senha); // Assim como
																	// um
																	// gerente,
																	// informações
																	// de login
																	// para
																	// usuarios
																	// são
																	// necessárias
		cliente.setGerente(gerente);
		cliente.setEmail(email);
		cliente.setTipoDePessoa(tipoDePessoa);
		cliente.setCpfCnpj(cpfCnpj);
		cliente.save();
		System.out.println("Cliente criado");
	}

	public static void atualiza(int id, Gerente gerente, String nome,
			String login, String email, String senha, TipoPessoa tipoDePessoa,
			String cpfCnpj) {
		Cliente cliente = get(id);

		// passando null você quer dizer que não é necessário atualizar esse
		// valor da entidade
		UsuarioControlador.atualiza(cliente, nome, login, senha); // Assim como
																	// um
																	// gerente,
																	// informações
																	// de login
																	// para
																	// usuarios
																	// são
																	// necessárias
		if (gerente != null)
			cliente.setGerente(gerente);
		if (email != null)
			cliente.setEmail(email);
		if (tipoDePessoa != null)
			cliente.setTipoDePessoa(tipoDePessoa);
		if (cpfCnpj != null)
			cliente.setCpfCnpj(cpfCnpj);
		cliente.save();
	}

	public static Cliente get(int id) {
		Sistema sistema = Sistema.getUnicaInstancia();
		return sistema.getEntityManager().get(Cliente.class, id);
	}

	public static Conta getConta(int id) {
		Sistema sistema = Sistema.getUnicaInstancia();
		return sistema.getEntityManager().get(Conta.class, id);
	}

	public static Cliente get(String login, String senha) {
		Sistema sistema = Sistema.getUnicaInstancia();
		Cliente[] clientes;
		try {
			clientes = sistema.getEntityManager().find(Cliente.class,
					"login = ? and senha = ?", login, senha);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			clientes = new Cliente[0];
			e.printStackTrace();
		}
		if (clientes.length == 0) {
			return null;
		}
		return clientes[0];
	}

	public static String exists(String login) {
		Sistema sistema = Sistema.getUnicaInstancia();
		Cliente[] clientes;
		try {
			clientes = sistema.getEntityManager().find(Cliente.class,
					"login = ?", login);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			clientes = new Cliente[0];
			e.printStackTrace();
		}
		if (clientes.length == 0) { // não existe
			return "false";
		}
		return "true";
	}

	public static ArrayList<Cliente> getAll() throws SQLException {
		Sistema sistema = Sistema.getUnicaInstancia();
		Cliente[] clientesArray = sistema.getEntityManager()
				.find(Cliente.class);
		ArrayList<Cliente> clientes = new ArrayList<Cliente>();
		sistema.fromArrayToArrayList(clientesArray, clientes);
		return clientes;
	}

	public static ArrayList<Cliente> getPessoasFisicas() throws SQLException {
		Sistema sistema = Sistema.getUnicaInstancia();
		Cliente[] pessoasFisicasArray = sistema.getEntityManager().find(
				Cliente.class, "tipoDePessoa = ?", TipoPessoa.FISICA);
		ArrayList<Cliente> pessoasFisicas = new ArrayList<Cliente>();
		sistema.fromArrayToArrayList(pessoasFisicasArray, pessoasFisicas);
		return pessoasFisicas;
	}

	public static ArrayList<Cliente> getPessoasJuridicas() throws SQLException {
		Sistema sistema = Sistema.getUnicaInstancia();
		Cliente[] pessoasJuridicasArray = sistema.getEntityManager().find(
				Cliente.class, "tipoDePessoa = ?", TipoPessoa.JURIDICA);
		ArrayList<Cliente> pessoasJuridicas = new ArrayList<Cliente>();
		sistema.fromArrayToArrayList(pessoasJuridicasArray, pessoasJuridicas);
		return pessoasJuridicas;
	}

	public static void delete(Cliente cliente) throws SQLException {
		Sistema sistema = Sistema.getUnicaInstancia();
		deleteContas(cliente);
		sistema.getEntityManager().delete(cliente);
	}

	public static void deleteContas(Cliente cliente) throws SQLException {
		Conta[] contas = cliente.getContas();
		for (Conta conta : contas) {
			ContaControlador.delete(conta);
		}
	}

	public static void delete(int id) throws SQLException {
		delete(get(id));
	}

	private static void addToBuilder(StringBuilder sb, String s) {
		sb.append(String.format("%s\n", s)); // adiciona um valor a cada linha
	}

	private static void addToBuilder(StringBuilder sb, int i) {
		sb.append(String.format("%d\n", i)); // adiciona um valor a cada linha
	}

	private static void addToBuilderSemPular(StringBuilder sb, String s) {
		sb.append(String.format("%s", s)); // adiciona um valor a cada linha
	}

	private static void addToBuilderSemPular(StringBuilder sb, int i) {
		sb.append(String.format("%d", i)); // adiciona um valor a cada linha
	}

	// Retorna na ordem: clienteId, gerenteId, nome, login, email, senha,
	// tipoDePessoa, cpfCnpj
	public static String parseString(Cliente cliente) {
		if (cliente == null)
			return "null";
		// StringBuilder tem a vantagem de não ficar alocando espaço para uma
		// string a cada mudança de valor
		StringBuilder sb = new StringBuilder();
		addToBuilder(sb, cliente.getID());
		addToBuilder(sb, cliente.getGerente().getID());
		addToBuilder(sb, cliente.getNome());
		addToBuilder(sb, cliente.getLogin());
		addToBuilder(sb, cliente.getEmail());
		addToBuilder(sb, cliente.getSenha());
		addToBuilder(sb,
				(cliente.getTipoDePessoa() == TipoPessoa.FISICA) ? "FISICA"
						: "JURIDICA");
		addToBuilderSemPular(sb, cliente.getCpfCnpj());
		return sb.toString();
	}

	// Retorna de todos os clientes passados na ordem: clienteId, gerenteId,
	// nome, login, email, senha, tipoDePessoa, cpfCnpj.
	// E depois termina passando a string END
	public static String parseString(ArrayList<Cliente> clientes) {
		if (clientes == null)
			return "null";
		// StringBuilder tem a vantagem de não ficar alocando espaço para uma
		// string a cada mudança de valor
		StringBuilder sb = new StringBuilder();
		for (Cliente cliente : clientes) {
			addToBuilder(sb, parseString(cliente));
		}
		addToBuilderSemPular(sb, "END");
		String s = sb.toString();
		return s;
	}
}
